package za.org.jcicada.comms.impl;

import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import za.org.jcicada.comms.IAcceptListener;
import za.org.jcicada.comms.IConnection;
import za.org.jcicada.comms.IKatcpSerializerStrategy;
import za.org.jcicada.comms.IMessageListener;

/**
 * Katcomms accept listener that accepts connections, keeps
 * track of them in a set and closes them as appropriate.
 *
 * Sub-classes must implement the createListener method (and
 * probably also a constructor).
 */
public abstract class AcceptListenerBase implements IAcceptListener {

    private final Log logger = LogFactory.getLog(AcceptListenerBase.class);

    /** List of client connections. */
    protected Set<IConnection> clients = new HashSet<IConnection>();

    /**
     * Create an IMessageListener for the given connection.
     *
     * Sub-classes should implement this method.
     */
    public abstract IMessageListener createListener(IConnection connection);

    /**
     * Accept new clients.
     * Part of the ICommsAcceptListener interface.
     *
     * @param connection  New connection from client.
     */
    @Override
    public void onAccept(IConnection connection) {
        clients.add(connection);
        IMessageListener listener = createListener(connection);
        try {
            connection.initialize(listener);
        } catch (IOException ex) {
            logger.error(String.format("Failed to attach sensor subject messager to client connection [%s].", connection), ex);
        }
    }

    /**
     * Called when clients need to be closed.
     * Part of the ICommsAcceptListener interface.
     *
     * @param connection  Connection to be closed.
     */
    @Override
    public void onClose(IConnection connection) {
        clients.remove(connection);
        try {
            connection.close();
        } catch (IOException ex) {
            logger.error("Failed to close client queue.", ex);
        }
    }
    
    /**
     * Default behaviour is that acceptors don't support katcp serialization
     */
    @Override
    public IKatcpSerializerStrategy getKatcpSerializerStrategy() {
    	return null;
    }

    /**
     * Get a list of clients.
     *
     * @return Set of attached clients.
     */
    public Set<IConnection> getClients() {
        return clients;
    }
}
